/**    
 * 文件名：MyVisualWords.java    
 *    
 * 版本信息：    
 * 日期：2014年3月27日    
 * xyj 足下 xyj 2014     
 * 版权所有    
 *    
 */
package learn.visual.words;

import static com.googlecode.javacpp.Loader.sizeof;
import static com.googlecode.javacv.cpp.opencv_core.CV_32FC1;
import static com.googlecode.javacv.cpp.opencv_core.CV_AUTOSTEP;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateMemStorage;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSeqElem;
import static com.googlecode.javacv.cpp.opencv_core.cvInitMatHeader;
import static com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE;
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import static com.googlecode.javacv.cpp.opencv_legacy.cvExtractSURF;
import static com.googlecode.javacv.cpp.opencv_legacy.cvSURFParams;

import java.util.ArrayList;
import java.util.List;

import com.googlecode.javacpp.FloatPointer;
import com.googlecode.javacv.cpp.opencv_core.CvMat;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_features2d;
import com.googlecode.javacv.cpp.opencv_legacy.CvSURFParams;
import com.googlecode.javacv.cpp.opencv_nonfree;

/**
 * @项目名称：opencv-test
 * @类名称：MyVisualWords
 * @类描述：
 * @创建人：zhuyi
 * @创建时间：2014年3月27日 下午2:20:01
 * @修改人：zhuyi
 * @修改时间：2014年3月27日 下午2:20:01
 * @修改备注：
 * @version
 * 
 */
public class MyVisualWords {

    private static int SURF_PARAM = 400;

    private static int DIM = 128;

    public static void main(String[] args) {

        opencv_features2d.initModule_features2d();
        opencv_nonfree.initModule_nonfree();

        // 以灰度方式读取图像
        IplImage image = cvLoadImage("art0009720016-l-n1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
        CvSeq keypoints = new CvSeq();
        CvSeq descriptors = new CvSeq();
        CvMemStorage storage = cvCreateMemStorage(0);
        extractSURF(image, keypoints, descriptors, storage);

        System.out.println(keypoints.total());
        System.out.println(descriptors.total());
        System.out.println(descriptors.elem_size());
        System.out.println(sizeof(FloatPointer.class));

        List<Float> data = new ArrayList<Float>();
        for (int i = 0; i < descriptors.total(); i++) {
            FloatPointer d = new FloatPointer(cvGetSeqElem(descriptors, i)); // 128次元ベクトル
            for (int j = 0; j < DIM; j++) {
                data.add(d.get(j));
            }
        }

        // dataをCvMat形式に変換
        // CvMatはdataを参照するためdataは解放されないので注意
        System.out.println(data.size());
        int rows = data.size() / DIM; // CvMatの行数（=DIM次元特徴ベクトルの本数）
        FloatPointer p = new FloatPointer(data.size());
        float[] _data = new float[data.size()];

        for (int i = 0; i < data.size(); i++) {
            _data[i] = data.get(i).floatValue();
        }
        p.put(_data);
        System.out.println(p.capacity());

        CvMat samples = new CvMat();
        cvInitMatHeader(samples, rows, DIM, CV_32FC1, p, CV_AUTOSTEP);

        System.out.println(samples);
    }

    /**
     * 从图片文件中抽出SURF特征值
     * 
     * @param[in] filename 图片文件名
     * @param[out] imageKeypoints KeyPoints
     * @param[out] imageDescriptors 各KeyPoint的SURF特征值
     * @param[out] storage 内存区域
     * @return int 如果成功，返回0， 失败返回1
     */
    public static int extractSURF(IplImage image, CvSeq keypoints, CvSeq descriptors, CvMemStorage storage) {

        CvSURFParams params = cvSURFParams(SURF_PARAM, 1);
        cvExtractSURF(image, null, keypoints, descriptors, storage, params, 0);

        return 0;
    }

}
